package k8s_agent

import (
	devcontainer_k8s_agent_module "code.gitea.io/gitea/modules/devstar_devcontainer/k8s_agent"
	devcontainer_api_v1 "code.gitea.io/gitea/modules/devstar_devcontainer/k8s_agent/api/v1"
	devcontainer_dto "code.gitea.io/gitea/modules/devstar_devcontainer/k8s_agent/dto"
	"code.gitea.io/gitea/modules/setting"
	"code.gitea.io/gitea/services/devstar_devcontainer/errors"
	devcontainer_k8s_agent_errors "code.gitea.io/gitea/services/devstar_devcontainer/k8s_agent/errors"
	devcontainer_service_options "code.gitea.io/gitea/services/devstar_devcontainer/options"
	"context"
	"fmt"
	apimachinery_api_metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// AssignDevcontainerGetting2K8sOperator 获取 k8s CRD 资源 DevcontainerApp 最新状态（需要根据用户传入的 wait 参数决定是否要阻塞等待 DevContainer 就绪）
func AssignDevcontainerGetting2K8sOperator(ctx *context.Context, opts *devcontainer_service_options.OpenDevcontainerAppDispatcherOptions) (*devcontainer_api_v1.DevcontainerApp, error) {

	// 0. 检查参数
	if ctx == nil || opts == nil || len(opts.Name) == 0 {
		return nil, devcontainer_k8s_agent_errors.ErrIllegalK8sAgentParams{
			FieldNameList: []string{"ctx", "opts", "opts.Name"},
		}
	}

	// 1. 获取 Dynamic Client
	client, err := devcontainer_k8s_agent_module.GetKubernetesClient(ctx)
	if err != nil {
		// 层层返回错误，结束数据库事务
		return nil, errors.ErrOperateDevcontainer{
			Action:  "Connect to k8s API Server",
			Message: err.Error(),
		}
	}

	// 2. 调用 modules 层 k8s Agent 获取 k8s CRD 资源 DevcontainerApp
	optsGetDevcontainer := &devcontainer_dto.GetDevcontainerOptions{
		GetOptions: apimachinery_api_metav1.GetOptions{},
		Name:       opts.Name,
		Namespace:  setting.Devstar.Devcontainer.Namespace,
		Wait:       opts.Wait,
	}
	devcontainerApp, err := devcontainer_k8s_agent_module.GetDevcontainer(ctx, client, optsGetDevcontainer)
	if err != nil {
		return nil, errors.ErrOperateDevcontainer{
			Action:  fmt.Sprintf("Open Devcontainer '%s' (wait=%v)", opts.Name, opts.Wait),
			Message: err.Error(),
		}
	}

	// 3. 成功获取最新的 DevcontainerApp，返回
	return devcontainerApp, nil
}
